package org.jeecg.modules.api.order.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.api.commissionlog.entity.CommissionLog;
import org.jeecg.modules.api.commissionlog.service.ICommissionLogService;
import org.jeecg.modules.api.member.entity.Member;
import org.jeecg.modules.api.member.service.IMemberService;
import org.jeecg.modules.api.officebalancelog.entity.OfficeBalanceLog;
import org.jeecg.modules.api.officebalancelog.service.IOfficeBalanceLogService;
import org.jeecg.modules.api.order.dto.CreateFxOrderReq;
import org.jeecg.modules.api.order.entity.Order;
import org.jeecg.modules.api.order.mapper.OrderMapper;
import org.jeecg.modules.api.order.service.IOrderService;
import org.jeecg.modules.api.setting.entity.Setting;
import org.jeecg.modules.api.setting.service.ISettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 分销订单
 * @Author: jeecg-boot
 * @Date: 2024-09-26
 * @Version: V1.0
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private IOfficeBalanceLogService officeBalanceLogService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private ISettingService settingService;
    @Autowired
    private ICommissionLogService commissionLogService;


    @Override
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) 事务不能跨库
    public Result createFxOrder(CreateFxOrderReq req) {
        String sourceOrderId = req.getOrderId();
        List<Order> orders = new ArrayList<>();
        List<CommissionLog> commissionLogs = new ArrayList<>();
        List<Member> members = new ArrayList<>();

        //检查订单是否已经分佣
        long count = this.count(new LambdaQueryWrapper<Order>()
                .eq(Order::getSourceOrderId, sourceOrderId)
                .eq(Order::getType, 1));
        if (count > 0) {
            return Result.error(StrUtil.format("订单：{} 该订单已存在", sourceOrderId));
        }

        int res = officeBalanceLogService.updateOrderStatus(sourceOrderId, 0, 1);//处理中
        if (res == 0) {
            return Result.error(StrUtil.format("订单：{} 该订单处理中", sourceOrderId));
        }
        OfficeBalanceLog balanceLog = officeBalanceLogService.getOne(new LambdaQueryWrapper<OfficeBalanceLog>()
                .eq(OfficeBalanceLog::getDelFlag, 0)
                .eq(OfficeBalanceLog::getOrderId, sourceOrderId));

//        if (balanceLog.getRecAmount() == null||balanceLog.getRecAmount().compareTo(BigDecimal.ZERO)<=0) {
//            officeBalanceLogService.updateOrderStatus(sourceOrderId,1,2);//处理完成
//            return Result.error(StrUtil.format("订单：{} 该订单没有分佣金额", sourceOrderId));
//        }
        //获取源用户id
        String sourceUserId = officeBalanceLogService.getSourceUserIdByLkdOrderId(balanceLog.getOrderId());
        if (StrUtil.isEmpty(sourceUserId)) {
            officeBalanceLogService.updateOrderStatus(sourceOrderId, 1, 2);//处理完成
            return Result.error(StrUtil.format("订单：{} 该订单未能查询源用户id", sourceOrderId));
        }

        Member member = memberService.getOne(new LambdaQueryWrapper<Member>()
                .eq(Member::getSourceMemberId, sourceUserId)
                .last("limit 1"));

        if (member == null) {
            officeBalanceLogService.updateOrderStatus(sourceOrderId, 1, 2);//处理完成
            return Result.error(StrUtil.format("订单：{} 该订单未能查询用户id", sourceOrderId));
        }

        //获取上级用户
        String fxTeamIds = member.getFxTeamIds();
        if (StrUtil.isEmpty(fxTeamIds)) {
            officeBalanceLogService.updateOrderStatus(sourceOrderId, 1, 2);//处理完成
            return Result.error(StrUtil.format("订单：{} 该订单无需分佣，用户没有上级分销商", sourceOrderId));
        }

        //获取套餐金额
        BigDecimal orderAmount = balanceLog.getOrderAmount().subtract(balanceLog.getFareAmount());
        Date createDate = balanceLog.getCreateDate();
        List<String> memberIds = Arrays.asList(fxTeamIds.split(","));
        Collections.reverse(memberIds);

//        for (int i = 0; i < memberIds.size(); i++) {


        Order order = new Order();
//            String level1MemberId = memberIds.get(i);
        memberService.updateLevel(member.getRecommendId().toString());
        Member recMember = memberService.getById(member.getRecommendId());
        Integer level = recMember.getLevel();
//            BigDecimal shareAmount = BigDecimal.ZERO;
//            //更新推荐人的等级状态-0：已执行 1：未执行
//            memberDb.setLevelState(1);
        log.info("{}", JSONObject.toJSONString(recMember));

        if (level != null && level != 0) {
            //检查有无分佣配置
            Setting setting = settingService.getOne(new LambdaQueryWrapper<Setting>()
                    .eq(Setting::getIsOpen, 1).eq(Setting::getLevel, level)
                    .last("limit 1"));
            if (setting == null) {
                return Result.error(StrUtil.format("订单：{} 操作失败系统没有进行分佣配置", sourceOrderId));
            }
            Integer firstPctSetting = setting.getFirstPct();
            Integer secondPct = setting.getSecondPct();
            List<Map<String, Object>> usersList = new ArrayList<>();
            if (memberIds.size() == 1) {
                Map<String, Object> map = new HashMap<>();
                String userId = memberIds.get(0);
                BigDecimal firstPct = BigDecimal.valueOf(firstPctSetting * 0.01);
                BigDecimal profit = orderAmount.multiply(firstPct);
                map.put("userId", userId);
                map.put("profit", profit);
                map.put("rate", firstPct);
                usersList.add(map);
            } else {
                Map<String, Object> map1 = new HashMap<>();

                BigDecimal firstPct = BigDecimal.valueOf(firstPctSetting * 0.01);
                BigDecimal secPct = BigDecimal.valueOf(secondPct * 0.01).multiply(firstPct);
                BigDecimal profit2 = orderAmount.multiply(secPct);

                BigDecimal newRate = BigDecimal.ONE.subtract(secPct);
                BigDecimal profit1 = orderAmount.multiply(newRate);
                String userId1 = memberIds.get(0);
                map1.put("userId", userId1);
                map1.put("profit", profit1);
                map1.put("rate", newRate);
                usersList.add(map1);

                Map<String, Object> map2 = new HashMap<>();
                String userId2 = memberIds.get(1);
                map2.put("userId", userId2);
                map2.put("profit", profit2);
                map2.put("rate", secPct);
                usersList.add(map2);
            }
            log.info("usersList profit :{}", JSONObject.toJSONString(usersList));
            for (int i = 0; i < usersList.size(); i++) {

                Map<String, Object> map = usersList.get(i);
                String recUserId = (String) map.get("userId");
                BigDecimal profit = (BigDecimal) map.get("profit");
                BigDecimal rate = (BigDecimal) map.get("rate");
                Member pMember = memberService.getById(recUserId);
                int type = i + 1;
                //订单编号
                String orderNo = String.valueOf(System.currentTimeMillis());
                order.setOrderNo(orderNo);
                order.setSourceOrderId(sourceOrderId);
                order.setOrderAmount(orderAmount);
                order.setOrderDate(createDate);
                order.setIsDelete(0);
                order.setTeamId(String.valueOf(pMember.getId()));//推荐人ID
                order.setTeamFyamount(profit);
                order.setTeamLevel(pMember.getLevel());
                order.setTeamPct(rate.toString());
                order.setUserId(String.valueOf(member.getId()));//下单用户ID
                order.setType(type);
                orders.add(order);

                //用户累计分佣
                BigDecimal beforeCommission = Optional.ofNullable(pMember.getCommission()).orElse(BigDecimal.ZERO);
                BigDecimal afterCommission = beforeCommission.add(profit);
                pMember.setCommission(afterCommission);
                //可提现
                BigDecimal beforeAmount = Optional.ofNullable(pMember.getWithdrawMoney()).orElse(BigDecimal.ZERO);
                BigDecimal afterAmount = beforeAmount.add(profit);
                pMember.setWithdrawMoney(afterAmount);
                members.add(pMember);

                //分佣日志
                CommissionLog commissionLog1 = new CommissionLog();
                commissionLog1.setOrderNo(orderNo);
                commissionLog1.setSourceOrderId(sourceOrderId);
                commissionLog1.setAmount(profit);
                commissionLog1.setMemberId(String.valueOf(pMember.getId()));
                commissionLog1.setLeve(String.valueOf(pMember.getLevel()));
                commissionLog1.setFyRatio(rate.toString());
                commissionLog1.setBeforeAmount(beforeAmount);
                commissionLog1.setAfterAmount(afterAmount);
                commissionLogs.add(commissionLog1);
            }
        }
        int ress = officeBalanceLogService.updateOrderStatus(sourceOrderId, 1, 2);//处理完成
        if (ress > 0) {
            //保存数据
            this.saveBatch(orders);
            if (commissionLogs != null) {
                commissionLogService.saveBatch(commissionLogs);
            }
            memberService.updateBatchById(members);
        }
        return Result.OK(StrUtil.format("订单：{} 分佣成功", sourceOrderId));
    }

    @Override
    public int getFxOrderNum(Long memberId) {

        Long count = this.count(new LambdaQueryWrapper<Order>().eq(Order::getTeamId, memberId));
        return count.intValue();
    }
}
